/*
 * VacationsPanel.java
 *
 * Created on 30 marzec 2007, 00:07
 */

package client;

import data.Employee;
import data.Team;
import data.VacQuota;
import data.Vacation;
import daychooser.DaysChooserControl;
import daychooser.DaysControl;
import daychooser.FieldSelectingEvent;
import daychooser.IFieldSelectingListener;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.rmi.RemoteException;
import java.util.Calendar;
import java.util.Date;
import java.util.Set;
import java.util.Vector;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import util.DatePeriod;

/**
 *
 * @author  Przemek
 */
public class VacationsPanel extends javax.swing.JPanel
{
    Team teamWithAll;
    Set<Employee> empsWithVac;
    Employee[] empsTable;
    
    Vector<Vacation> vacations = new Vector<Vacation>();
    
    
    Date from;
    Date to;
    
    /** Creates new form VacationsPanel */
    public VacationsPanel()
    {
        initComponents();
        fillTeamsComboBox();
    }
    
    private void fillTeamsComboBox()
    {
        try
        {
            Set<Team> teams = VacationClient.getInstance().getRemoteServer().getTeams();
            jComboBoxTeam.setModel( new DefaultComboBoxModel( teams.toArray() ));
        } catch (RemoteException ex)
        {
            VacationClient.printException( ex, this );
        }
    }
    
    private boolean isTeamDatesCorrect()
    {
        if( jComboBoxTeam.getSelectedItem() == null )
        {
            JOptionPane.showMessageDialog( this, "You must select team", "Error", JOptionPane.ERROR_MESSAGE );
            return false;
        }
        
        if( dateChooserFrom.getDate() == null )
        {
            JOptionPane.showMessageDialog( this, "You must select from date", "Error", JOptionPane.ERROR_MESSAGE );
            return false;
        }
        
        if( dateChooserTo.getDate() == null )
        {
            JOptionPane.showMessageDialog( this, "You must select to date", "Error", JOptionPane.ERROR_MESSAGE );
            return false;
        }
                
        return true;        
    }
    
    private void fillVacations( Team t, Date from, Date to )
    {
        this.from = from;
        this.to = to;
        try
        {   
            teamWithAll = VacationClient.getInstance().getRemoteServer().reloadTeam( t, true, true );            
            empsWithVac = VacationClient.getInstance().getRemoteServer().reloadEmployeesWithVacations( teamWithAll.getMembers() );
            empsTable = new Employee[ empsWithVac.size()];
            empsWithVac.toArray( empsTable );
        }
        catch (RemoteException ex)
        {
            VacationClient.printException( ex, this );
        }
        
        setLabelLimits( );
        setLabelActual( );
        fillVacationsDetail();
    }
    
    private void setLabelLimits(  )
    {
        daysLabelLimits.setStartDate( from );
        daysLabelLimits.setEndDate( to );
        daysLabelLimits.setLabels( getQuotaLimits( teamWithAll, from, to ) );
    }
    
    private void setLabelActual( )
    {
        daysLabelActual.setStartDate( from );
        daysLabelActual.setEndDate( to );
        daysLabelActual.setLabels( getQuotaActual( empsWithVac, from, to ) );
    }
    
    private void fillVacationsDetail()
    {
        jPanelVacation.removeAll();
        
        int y = 0;
        
        for( Employee e : empsWithVac )
        {
            addControlToVacationPanel( getDaysChooserForEmpl( e ), 0, y );
            addControlToVacationPanel( new JLabel( e.getName() ), 1, y );
            
            y++;
        };
        
        int compHeight = 0;
        if( jPanelVacation.getComponentCount() > 0 )
            compHeight = jPanelVacation.getComponent( 0 ).getHeight();
        
        jPanelVacation.setSize( jPanelVacation.getWidth(), compHeight * y );
        
    }
    
    private JLabel getLabelForEmpl( Employee e )
    {
        JLabel result = new JLabel();
        
        result.setText( e.getName() );
       
        return result;
    }
    
    private DaysChooserControl getDaysChooserForEmpl( Employee e )
    {
        DaysChooserControl result = new DaysChooserControl( from, to );
        
        result.setBackground( Color.WHITE );
        result.setForeground( Color.CYAN  );
        
        result.addFieldSelectingListener( this.selectListener );
        
        for( Vacation v : e.getVacations() )
            result.setSelectedDay( v.getVacationDate(), true );
        
        return result;
    }
    
    private void addControlToVacationPanel( JComponent c, int x, int y )
    {
        GridBagConstraints constr = new GridBagConstraints();
        constr.gridx = x;
        constr.gridy = y;
        constr.weightx = (x == 0) ? 1.0 : 0.0;
        constr.insets.top = 5;
        constr.insets.bottom = 5;
        constr.fill = (x == 0) ? GridBagConstraints.BOTH : GridBagConstraints.NONE;
        
        jPanelVacation.add( c, constr );
    }
    
    private Integer[] getQuotaLimits( Team teamWithQuotas, Date from, Date to )
    {
        Integer[] result = new Integer[ DaysControl.getDaysBetween( from, to ) +1 ];
        
        DatePeriod dp = new DatePeriod( from, to );
        
        Calendar day = Calendar.getInstance();
        day.setTime( from );
        
        for( int i = 0; i < result.length; i++ )
        {
            int limit = 0;            
            
            for( VacQuota vq : teamWithQuotas.getQuotas( dp ) )
            {
                DatePeriod quotaPeriod = new DatePeriod( vq.getFromDate(), vq.getToDate() );
                if( quotaPeriod.contains( day.getTime() ) )
                    limit += vq.getQuota();
            }
            
            result[ i ] = limit;
            day.add( Calendar.DATE, 1 );
        }
        
        return result;
    }
    
    private Integer[] getQuotaActual( Set<Employee> empsWithVac, Date from, Date to )
    {
        Integer[] result = new Integer[ DaysControl.getDaysBetween( from, to ) +1 ];
        
        DatePeriod dp = new DatePeriod( from, to );
        
        Calendar day = Calendar.getInstance();
        day.setTime( from );
        
        for( int i = 0; i < result.length; i++ )
        {
            int empsNo = empsWithVac.size();
            
            for( Employee e : empsWithVac )
            {
                for( Vacation v : e.getVacations() )
                {
                    if( day.getTime().equals( v.getVacationDate()) )
                    {
                        empsNo--;
                    }                
                }
            }
            
            result[ i ] = empsNo;
            day.add( Calendar.DATE, 1);
        }
        
        return result;
    }
    
    private void reloadVacations()
    {
        Calendar c = Calendar.getInstance();
        c.setTime( from );
        
        vacations.removeAllElements();
        
        while( c.getTime().before( to ) || c.getTime().equals( to ) )
        {
            Vacation v = null;
            try
            {
                v = VacationClient.getInstance().getRemoteServer()
                    .getVacation(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
                v = VacationClient.getInstance().getRemoteServer().reloadVacationWithEmployees( v );
                
                vacations.add( v );
            }
            catch (RemoteException ex)
            {
                VacationClient.printException( ex, this );
            }
            
            c.add( Calendar.DATE, 1 );
        }
    }
    
    private void setEmployees()
    {        
        reloadVacations();
        
        for( int i = 0; i < empsTable.length; i++ )
        {
            DaysChooserControl dc = (DaysChooserControl)jPanelVacation.getComponent( 2*i );
            
            //TODO: debug
            if( !((JLabel)jPanelVacation.getComponent( 2*i + 1 )).getText().equals( empsTable[i].getName() ) )
                JOptionPane.showMessageDialog( this, "Zly employee blad!");
            
            setEmployeeVacations( empsTable[i], dc.getSelectedFields() );
        }
    }
    
    private void setEmployeeVacations( Employee e, int[] selectedFields )
    {
        for( int i = 0; i < vacations.size(); i++ )
        {
            e.getVacations().remove( vacations.get(i) );
            vacations.get( i ).getEmployees().remove( e );
        }
        
        for( int i : selectedFields )
        {   
            e.getVacations().add( vacations.get( i ) );
            vacations.get( i ).getEmployees().add( e );
        }
    }
    
    private IFieldSelectingListener selectListener = new IFieldSelectingListener()
    {
        public void fieldSelecting(FieldSelectingEvent evt)
        {
            evt.setSelectable( !(evt.isSelecting() &&
                    (Integer)daysLabelLimits.getLabel( evt.getFieldNo() ) >= (Integer)daysLabelActual.getLabel( evt.getFieldNo()) ));
            if( !evt.isSelectable() )
                return;
            
            Integer actual = (Integer)daysLabelActual.getLabel( evt.getFieldNo() );
            
            if(evt.isSelecting())
                actual--;
            else
                actual++;
            
            daysLabelActual.setLabel( evt.getFieldNo(), actual );
            
        }
    };
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents()
    {
        jComboBoxTeam = new javax.swing.JComboBox();
        dateChooserFrom = new datechooser.DateChooserControl();
        dateChooserTo = new datechooser.DateChooserControl();
        jButtonShow = new javax.swing.JButton();
        daysLabelLimits = new daychooser.DaysLabelControl();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        daysLabelActual = new daychooser.DaysLabelControl();
        jScrollPane1 = new javax.swing.JScrollPane();
        jPanelVacation = new javax.swing.JPanel();
        jButtonSet = new javax.swing.JButton();

        setLayout(null);

        setMinimumSize(new java.awt.Dimension(640, 480));
        add(jComboBoxTeam);
        jComboBoxTeam.setBounds(30, 30, 160, 22);

        add(dateChooserFrom);
        dateChooserFrom.setBounds(200, 30, 160, 21);

        add(dateChooserTo);
        dateChooserTo.setBounds(370, 30, 160, 21);

        jButtonShow.setText("Show");
        jButtonShow.setMargin(new java.awt.Insets(2, 2, 2, 2));
        jButtonShow.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                jButtonShowActionPerformed(evt);
            }
        });

        add(jButtonShow);
        jButtonShow.setBounds(550, 30, 70, 23);

        daysLabelLimits.setBackground(new java.awt.Color(255, 255, 255));
        add(daysLabelLimits);
        daysLabelLimits.setBounds(70, 80, 600, 40);

        jLabel1.setText("Team");
        add(jLabel1);
        jLabel1.setBounds(30, 10, 50, 14);

        jLabel2.setText("From");
        add(jLabel2);
        jLabel2.setBounds(200, 10, 40, 14);

        jLabel3.setText("To");
        add(jLabel3);
        jLabel3.setBounds(370, 10, 40, 14);

        jLabel4.setText("Limits");
        add(jLabel4);
        jLabel4.setBounds(14, 90, 50, 14);

        jLabel5.setText("Actual");
        add(jLabel5);
        jLabel5.setBounds(14, 145, 50, 14);

        daysLabelActual.setBackground(new java.awt.Color(255, 255, 255));
        add(daysLabelActual);
        daysLabelActual.setBounds(70, 130, 600, 40);

        jPanelVacation.setLayout(new java.awt.GridBagLayout());

        jScrollPane1.setViewportView(jPanelVacation);

        add(jScrollPane1);
        jScrollPane1.setBounds(30, 190, 640, 300);

        jButtonSet.setText("Set");
        jButtonSet.setMargin(new java.awt.Insets(2, 2, 2, 2));
        jButtonSet.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                jButtonSetActionPerformed(evt);
            }
        });

        add(jButtonSet);
        jButtonSet.setBounds(600, 510, 70, 23);

    }// </editor-fold>//GEN-END:initComponents

    private void jButtonSetActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButtonSetActionPerformed
    {//GEN-HEADEREND:event_jButtonSetActionPerformed
        setEmployees();
        try
        {            
            empsWithVac = VacationClient.getInstance().getRemoteServer().saveEmployees( empsWithVac );
        }
        catch (RemoteException ex)
        {
            VacationClient.printException( ex, this );
        }
    }//GEN-LAST:event_jButtonSetActionPerformed

    private void jButtonShowActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButtonShowActionPerformed
    {//GEN-HEADEREND:event_jButtonShowActionPerformed
        if( !isTeamDatesCorrect() )
            return;
        
        fillVacations( (Team) jComboBoxTeam.getSelectedItem(),
                       dateChooserFrom.getDate(), dateChooserTo.getDate() );
    }//GEN-LAST:event_jButtonShowActionPerformed
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private datechooser.DateChooserControl dateChooserFrom;
    private datechooser.DateChooserControl dateChooserTo;
    private daychooser.DaysLabelControl daysLabelActual;
    private daychooser.DaysLabelControl daysLabelLimits;
    private javax.swing.JButton jButtonSet;
    private javax.swing.JButton jButtonShow;
    private javax.swing.JComboBox jComboBoxTeam;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JPanel jPanelVacation;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration//GEN-END:variables
    
}
